﻿'Copyright 2010 Jan Ruhlaender

'Licensed under the Apache License, Version 2.0 (the "License");
'you may not use this file except in compliance with the License.
'You may obtain a copy of the License at

'http://www.apache.org/licenses/LICENSE-2.0

'Unless required by applicable law or agreed to in writing, software
'distributed under the License is distributed on an "AS IS" BASIS,
'WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
'See the License for the specific language governing permissions and
'limitations under the License.

Imports System.Globalization
Imports System.Management

Module uptime

    ''' <summary>
    ''' Reads the Uptime of the OS from WMI.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' I found this function at: http://blogs.clearscreen.com/dtax/archive/2007/01/19/5985.aspx
    ''' Thanks to Jesus Jimenez
    ''' </remarks>
    Private Function GetUptimeFromWMI() As TimeSpan

        Dim lastBootTime As DateTime
        ' To store the datetime value from WMI in cimDateTime Format
        ' more Infos at: http://www.openpegasus.org/manual/CIMDateTime.html
        Dim cimDateTimeStr As String

        ' Timespan Object to store the result
        Dim result As TimeSpan = New TimeSpan()

        ' Objects needed to interact with WMI
        Dim management As New ManagementClass("Win32_OperatingSystem")
        Dim managementObjColl As ManagementObjectCollection = management.GetInstances()

        ' Loop through the instances
        For Each mngObj As ManagementObject In managementObjColl

            cimDateTimeStr = mngObj("LastbootUpTime")
            lastBootTime = ManagementDateTimeConverter.ToDateTime(cimDateTimeStr)

            If lastBootTime <> DateTime.MinValue Then
                result = Now.Subtract(lastBootTime)
            End If
        Next

        Return result

    End Function

    ''' <summary>
    ''' Writes the current Uptime to stdout
    ''' </summary>    
    Private Sub WriteUptimeToStdOut()
        Dim uptime As TimeSpan

        ' Get uptime since last start (complete boot) of windows. 
        ' Setting PC to Hibernate doesn't reset the system uptime.
        uptime = GetUptimeFromWMI()

        Console.Write(" uptime ")
        If uptime.Days > 0 Then
            Console.Write(String.Format(CultureInfo.InvariantCulture, "{0} days, ", uptime.Days))
        End If
        Console.Write(String.Format(CultureInfo.InvariantCulture, "{0:d2}:{1:d2}:{2:d2}", uptime.Hours, uptime.Minutes, uptime.Seconds))

    End Sub

    ''' <summary>
    ''' Program Entry
    ''' </summary>    
    Sub Main(ByVal args As String())

        If args.Length > 1 OrElse _
          (args.Length = 1 AndAlso Not args(0).Equals("-v", StringComparison.OrdinalIgnoreCase)) Then

            ' Write usage Help.
            Console.WriteLine("usage: Uptime [-V]")
            Console.WriteLine("    -V   display version")

        ElseIf args.Length = 1 Then

            ' Write Version Information
            Console.WriteLine("version " & My.Application.Info.Version.ToString(3))

        Else

            ' Display current time
            Console.Write(String.Format(CultureInfo.InvariantCulture, " {0:T}", Now))

            ' Write current uptime to stdout
            WriteUptimeToStdOut()

            ' absließenden Zeilenumbruch schreiben
            Console.WriteLine()

        End If

    End Sub

End Module
